// middleware/operLog.js
import operLogService from "@/service/operLogs.service";
import { getClientIp } from "@/utils/formate";
import { Context, Next } from "koa";

const operLogMiddleware = async (ctx: Context, next: Next) => {
  const start = Date.now();
  const requestTime = new Date();

  try {
    await next();
    if (ctx.method !== "GET") {
      const ip = getClientIp(ctx);
      const logData = {
        title: getTitleByUrl(ctx.url), // 根据 URL 映射操作模块
        business_type: getBusinessType(ctx.method), // 根据请求方法映射业务类型
        method: ctx.route?.path || ctx.url, // 路由路径或原始 URL
        request_method: ctx.method,
        oper_name: ctx.state.user?.username || "unknown", // 从上下文中获取用户名
        oper_url: ctx.url,
        oper_ip: ip,
        oper_param: JSON.stringify({
          query: ctx.query,
          body: ctx.request.body,
        }),
        json_result: JSON.stringify(ctx.body),
        status: ctx.status >= 400 ? 1 : 0, // 400+ 状态码标记为异常
        error_msg: "",
        oper_time: requestTime,
      };

      // 异步记录日志（不阻塞响应）
      operLogService.add(logData).catch((err) => {
        console.error("操作日志记录失败:", err);
      });
    }
  } catch (err: any) {
    const ip = getClientIp(ctx);
    // 错误处理
    const logData = {
      title: getTitleByUrl(ctx.url),
      business_type: getBusinessType(ctx.method),
      method: ctx.route?.path || ctx.url,
      request_method: ctx.method,
      oper_name: ctx.state.user?.username || "unknown",
      oper_url: ctx.url,
      oper_ip: ip,
      oper_param: JSON.stringify({
        query: ctx.query,
        body: ctx.request.body,
      }).substring(0, 2000),
      json_result: JSON.stringify(ctx.body),
      status: 1, // 标记为异常
      error_msg: err.message.substring(0, 2000),
      oper_time: requestTime,
    };

    operLogService.add(logData).catch((err) => {
      console.error("错误日志记录失败:", err);
    });

    throw err;
  }
};

function getTitleByUrl(url: string) {
  if (url.startsWith("/api/user")) return "用户管理";
  if (url.startsWith("/api/role")) return "角色管理";
  if (url.startsWith("/api/menu")) return "菜单管理";
  if (url.startsWith("/api/operLog")) return "操作日志";
  if (url.startsWith("/api/login")) return "登录";
  return "其他";
}

function getBusinessType(method: string) {
  switch (method) {
    case "POST":
      return 1; // 新增
    case "PUT":
      return 2; // 修改
    case "DELETE":
      return 3; // 删除
    default:
      return 0; // 其他
  }
}

export default operLogMiddleware;
